package com.tbit.uqbike.service.business.impl;

import com.tbit.uqbike.object.pojo.CouponMeal;
import com.tbit.uqbike.object.pojo.StatPark;
import com.tbit.uqbike.object.pojo.User;
import com.tbit.uqbike.object.pojo.UserMealLog;
import com.tbit.uqbike.service.business.UserMealLogService;
import com.tbit.uqbike.webmanager.dao.core.CouponMealDao;
import com.tbit.uqbike.webmanager.dao.core.UserDao;
import com.tbit.uqbike.webmanager.dao.log.UserMealLogDao;
import com.tbit.uqbike.webmanager.util.DateUtils;
import com.tbit.uqbike.webmanager.util.StringUtils;
import com.tbit.utils.DateTimeUtil;
import com.tbit.utils.NullUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户购买套餐日志Service业务层处理
 *
 * @author jing
 * @date 2021-05-25
 */
@Service
public class UserMealLogServiceImpl implements UserMealLogService {
    @Autowired
    private UserMealLogDao userMealLogDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private CouponMealDao couponMealDao;

    /**
     * 查询用户购买套餐日志列表
     *
     * @param userMealLog 用户购买套餐日志
     * @return 用户购买套餐日志
     */
    @Override
    public List<UserMealLog> selectUserMealLogList(UserMealLog userMealLog) {
        Map<Integer, String> phoneMap = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        if (!selectUserByphone(userMealLog, phoneMap, map)) {
            return new ArrayList<>();
        }
        List<UserMealLog> userMealLogs = userMealLogDao.selectUserMealLogList(userMealLog);
        if (StringUtils.isNotEmpty(userMealLogs)) {
            map.put("userIds", userMealLogs.stream().map(UserMealLog::getUserId).distinct().collect(Collectors.toList()));
            phoneMap = userDao.getByUserIds(map).stream().collect(Collectors.toMap(User::getUserId, User::getPhone, (x1, x2) -> x1));
            Map<Integer, String> finalPhoneMap = phoneMap;
            userMealLogs.forEach(mealLog -> {
                CouponMeal couponMeal = couponMealDao.selectCouponMealById(mealLog.getMealId());
                mealLog.setPhone(finalPhoneMap.get(mealLog.getUserId()));
                if (!NullUtils.isEmpty(couponMeal)) {
                    mealLog.setName(couponMeal.getName());
                }

            });
        }
        return userMealLogs;
    }

    @Override
    public int selectCount(UserMealLog userMealLog) {
        Map<Integer, String> phoneMap = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        if (!selectUserByphone(userMealLog, phoneMap, map)) {
            return 0;
        }
        return userMealLogDao.selectCount(userMealLog);
    }

    @Override
    public boolean selectUserByphone(UserMealLog userMealLog, Map<Integer, String> phoneMap, Map<String, Object> map) {
        if (StringUtils.isNotNull(userMealLog.getPhone())) {
            map.put("accountId", userMealLog.getAccountId());
            map.put("phone", userMealLog.getPhone());
            List<User> users = userDao.getByAccountIdAndPhone(map);
            if (StringUtils.isNotEmpty(users)) {
                userMealLog.setUserId(users.get(0).getUserId());
                phoneMap.put(users.get(0).getUserId(), userMealLog.getPhone());
            } else {
                return false;
            }
        }
        return true;
    }

    @Override
    public List<StatPark> selectByTime(UserMealLog userMealLog) {
        List<String> daysStr = DateTimeUtil.findDaysStr(DateTimeUtil.formatDateYMD(DateUtils.parseDate(userMealLog.getParams().get("beginTime"))), DateTimeUtil.formatDateYMD(DateUtils.parseDate(userMealLog.getParams().get("endTime"))));
        List<StatPark> maps = userMealLogDao.selectByTime(userMealLog);
        Map<String, StatPark> dayMap = maps.stream().collect(Collectors.toMap(StatPark::getName, Function.identity()));
        daysStr.forEach(day -> {
            if (!dayMap.containsKey(day)) {
                maps.add(new StatPark(0, 0, day));
            }
        });
        maps.sort(Comparator.comparing(StatPark::getName));
        return maps;
    }
}
